/**
 * 
 */
package com.gragra.sampling.binary;
import com.gragra.util.BooleanInterweave;
import it.unimi.dsi.fastutil.longs.Long2DoubleAVLTreeMap;
/**
 * @author Christoph Teichmann
 * 15.09.2013
 */
public class AVLTripleCounter
{
	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString()
	{return "AVLTripleCounter [counter=" + this.counter + "]";}
	/**
	 * 
	 * @param from
	 * @param to
	 * @param middle
	 * @param val
	 */
	public void setVal(short from,short to,short middle,double val)
	{
		long full = makeFull(from, to, middle);
		handleVal(val, full);
	}
	/**
	 * @param val
	 * @param full
	 */
	private void handleVal(double val, long full)
	{
		if(val==counter.defaultReturnValue())
		{counter.remove(full);}
		else
		{counter.put(full, val);}
	}
	/**
	 * 
	 */
	private final Long2DoubleAVLTreeMap counter;
	{
		counter = new Long2DoubleAVLTreeMap();
		counter.defaultReturnValue(0.0);
	}
	/**
	 * 
	 * @param from
	 * @param to
	 * @param middle
	 * @param by
	 */
	public double changeVal(short from,short to,short middle,double add)
	{
		long full = makeFull(from, to, middle);
		double val = counter.get(full);
		val += add;
		handleVal(val, full);
		return val;
	}
	/**
	 * @param from
	 * @param to
	 * @param middle
	 * @return
	 */
	private long makeFull(short from, short to, short middle)
	{
		int cord = BooleanInterweave.combine(from, to);
		long full = BooleanInterweave.combine(cord,(int) middle);
		return full;
	}
	/**
	 * 
	 * @param from
	 * @param to
	 * @param middle
	 * @return
	 */
	public double getAmount(short from,short to,short middle)
	{
		long full = makeFull(from, to, middle);
		return counter.get(full);
	}
	/**
	 * 
	 */
	public void clear()
	{this.counter.clear();}
}